home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / mach / sun4.md / bootSysAsm.s < prev    next >
Text File  |  1992-12-18  |  10KB  |  313 lines

  1. /*
  2.  * bootSysAsm.s -
  3.  *
  4.  *     Contains code that is the first executed at boot time.
  5.  *
  6.  * Copyright (C) 1985 Regents of the University of California
  7.  * All rights reserved.
  8.  */
  9.  
  10. .seg    "data"
  11. .asciz "$Header: /cdrom/src/kernel/Cvsroot/kernel/mach/sun4.md/bootSysAsm.s,v 9.4 92/08/10 17:58:47 mgbaker Exp $ SPRITE (Berkeley)"
  12. .align 8
  13. .seg    "text"
  14.  
  15. #include "machConst.h"
  16. #include "machAsmDefs.h"
  17.  
  18. /*
  19.  * "Start" is used for the -e option to the loader.  "SpriteStart" is
  20.  * used for the prof module, which prepends an underscore to the name of
  21.  * global variables and therefore can't find "_start".
  22.  *
  23.  * I use a lot global registers here for start up.  Elsewhere I'm careful.
  24.  */
  25.  
  26. .align 8
  27. .seg    "text"
  28. .globl    start
  29. .globl    _spriteStart
  30. start:
  31. _spriteStart:
  32.        /* 
  33.         * Believe it or not, we're running in the middle of our stack. 
  34.     * We are placed here by the bootstrap loading which starts us
  35.     * running at 0x4000. We quickly jump out of the stack.
  36.     */
  37.     ba    realStart
  38.     nop
  39. .skip    (MACH_KERN_STACK_SIZE-0x4000)
  40. realStart:
  41. #ifdef sun4c
  42.     mov    %o0, %g7            /* save romvec pointer */
  43. #endif
  44.     mov    %psr, %g1
  45.     or    %g1, MACH_DISABLE_INTR, %g1    /* lock out interrupts */
  46.     andn    %g1, MACH_CWP_BITS, %g1        /* set cwp to 0 */
  47.     set    MACH_ENABLE_FPP, %g2
  48.     andn    %g1, %g2, %g1            /* disable fp unit */
  49.     mov    %g1, %psr
  50.     mov    0x2, %wim    /* set wim to window right behind us */
  51.  
  52.     /*
  53.      * The kernel has been loaded into the wrong location.
  54.      * We copy it to the right location by copying up 8 Meg worth of pmegs.
  55.      * NOT done in all contexts!  8 Meg should be enough for the whole
  56.      * kernel.  We copy to the correct address, MACH_KERN_START which is
  57.      * before MACH_CODE_START, which is where we told the linker that the
  58.      * kernel would be loaded.  In this code, %g1 is the destination
  59.      * segment, %g2 is the last source segment, %g3 is the source segment,
  60.      * and %g5 contains seg size.  %g6 is used to hold the pmeg pointer.
  61.      */
  62.     set    VMMACH_SEG_SIZE, %g5        /* for additions */
  63. #ifdef sun4c
  64.     set    0x400000, %g2            /* last source addr */
  65. #else
  66.     set    0x800000, %g2            /* last source addr */
  67. #endif
  68.     clr    %g3                /* start with 0th segment */
  69.     set    MACH_KERN_START, %g1        /* pick starting segment */
  70. loopStart:
  71. #ifdef sun4c
  72.     lduba    [%g3] VMMACH_SEG_MAP_SPACE, %g6
  73. #else
  74.     lduha    [%g3] VMMACH_SEG_MAP_SPACE, %g6
  75. #endif
  76.                     /* set segment to point to new pmeg */
  77. #ifdef sun4c
  78.     stba    %g6, [%g1] VMMACH_SEG_MAP_SPACE
  79. #else
  80.     stha    %g6, [%g1] VMMACH_SEG_MAP_SPACE
  81. #endif
  82.     add    %g3, %g5, %g3            /* increment source segment */
  83.     add    %g1, %g5, %g1            /* increment dest segment */
  84.     cmp    %g3, %g2            /* last segment? */
  85.     bne    loopStart            /* if not, continue */
  86.     nop
  87.  
  88. /*
  89.  * Force a non-PC-relative jump to the real start of the kernel.
  90.  */
  91.     set    begin, %g1
  92.     jmp    %g1                /* jump to "begin" */
  93.     nop
  94. begin:
  95.     /*
  96.      * Zero out the bss segment.
  97.      */
  98.     set    _edata, %g2
  99.     set    _end, %g3
  100.     cmp    %g2, %g3    /* if _edata == _end, don't zero stuff. */
  101.     be    doneZeroing
  102.     nop
  103.     clr    %g1
  104. zeroing:
  105.     /*
  106.      * Use store doubles for speed.  Both %g0 and %g1 are zeroes.
  107.      */
  108.     std    %g0, [%g2]
  109.     add    %g2, 0x8, %g2
  110.     cmp    %g2, %g3
  111.     bne    zeroing
  112.     nop
  113. doneZeroing:
  114.     /*
  115.      * Find out how many register windows we have.
  116.      */
  117.     mov    %g0, %wim
  118.     save
  119.     mov    %psr, %g1
  120.     restore
  121.     mov    0x2, %wim    /* set wim to window right behind us */
  122.     and    %g1, MACH_CWP_BITS, %g1
  123.     sethi    %hi(_machWimShift), %g2
  124.     st    %g1, [%g2 + %lo(_machWimShift)]
  125.     add    %g1, 1, %g1
  126.     sethi    %hi(_machNumWindows), %g2
  127.     st    %g1, [%g2 + %lo(_machNumWindows)]
  128.     /*
  129.      * Now set the stack pointer to my own stack for the first kernel
  130.      * process.  The stack grows towards low memory.  I start it at
  131.      * the beginning of the text segment (CAREFUL: if loading demand-paged,
  132.      * then the beginning of the text segment is 32 bytes before the
  133.      * first code.  Set it really at the beginning of the text segment and
  134.      * not at the beginning of the code.), and it can grow up to
  135.      * MACH_KERN_START.
  136.      *
  137.      * The %fp points to top word on stack of one's caller, so it points
  138.      * to the base of our stack.  %sp points to the top word on the
  139.      * stack for our current stack frame.   This must be set at least
  140.      * to enough room to save our in registers and local registers upon
  141.      * window overflow (and for main to store it's arguments, although it
  142.      * doesn't have any...).
  143.      */
  144.     set    MACH_STACK_START, %fp
  145.     set    (MACH_STACK_START - MACH_FULL_STACK_FRAME), %sp
  146.     andn    %sp, 0x7, %sp            /* double-word aligned */
  147.  
  148.     /*
  149.      * Now set up initial trap table by copying machProtoVectorTable
  150.      * into reserved space at the correct alignment.  The table must
  151.      * be aligned on a MACH_TRAP_ADDR_MASK boundary, and it contains
  152.      * ~MACH_TRAP_ADDR_MASK + 1 bytes.  We copy doubles (8 bytes at
  153.      * a time) for speed.  %g1 is source for copy, %g2 is destination,
  154.      * %g3 is the counter copy, %g4 and %g5 are the registers used for
  155.      * the double-word copy, %l1 is for holding the size of the table,
  156.      * and %l2 contains the number of bytes to copy.  %g6 stores the
  157.      * original destination, so that we can do some further copies, and
  158.      * so that we can put it into the tbr..
  159.      */
  160.     set    machProtoVectorTable, %g1        /* g1 contains src */
  161.     set    reserveSpace, %g2            /* g2 to contain dest */
  162.     set    (1 + ~MACH_TRAP_ADDR_MASK), %l1
  163.     set    ((1 + ~MACH_TRAP_ADDR_MASK) / 8), %l2    /* # bytes to copy */
  164.     add    %g2, %l1, %g2                /* add size of table */
  165.     and    %g2, MACH_TRAP_ADDR_MASK, %g2        /* align to 4k bound. */
  166.     mov    %g2, %g6                /* keep value of dest */
  167.     clr    %g3                    /* clear counter */
  168. copyingTable:
  169.     ldd    [%g1], %g4                /* copy first 2 words */
  170.     std    %g4, [%g2]
  171.     ldd    [%g1 + 8], %g4                /* next 2 words */
  172.     std    %g4, [%g2 + 8]
  173.     add    %g2, 16, %g2                /* incr. destination */
  174.     add    %g3, 2, %g3                /* incr. counter */
  175.     cmp    %g3, %l2                /* how many copies */
  176.     bne    copyingTable
  177.     nop
  178.  
  179.     /*
  180.      * Now copy in the overflow and underflow trap code.  These traps
  181.      * bypass the regular preamble and postamble for speed, and because
  182.      * they are coded so that the only state they need save is the psr.
  183.      * %g6 was the trap table address saved from above.
  184.      */
  185.     set    machProtoWindowOverflow, %g1        /* new src */
  186.     set    MACH_WINDOW_OVERFLOW, %g2        /* get trap offset */
  187.     add    %g6, %g2, %g2                /* offset in table */
  188.     ldd    [%g1], %g4                /* copy first 2 words */
  189.     std    %g4, [%g2]
  190.     ldd    [%g1 + 8], %g4                /* copy next 2 words */
  191.     std    %g4, [%g2 + 8]
  192.  
  193.     set    machProtoWindowUnderflow, %g1        /* new src */
  194.     set    MACH_WINDOW_UNDERFLOW, %g2        /* get trap type */
  195.     add    %g6, %g2, %g2                /* offset in table */
  196.     ldd    [%g1], %g4                /* copy first 2 words */
  197.     std    %g4, [%g2]
  198.     ldd    [%g1 + 8], %g4                /* copy next 2 words */
  199.     std    %g4, [%g2 + 8]
  200.     /*
  201.      * Now copy the handler for non-maskable asynchronous memory error
  202.      * interrupts.  We're going to die anyway on these errors, so all
  203.      * we want to do is grab information and put it into registers.
  204.      */
  205.     set    machProtoLevel15Intr, %g1        /* new src */
  206.     set    MACH_LEVEL15_INT, %g2            /* get trap offset */
  207.     add    %g6, %g2, %g2                /* offset in table */
  208.     ldd    [%g1], %g4                /* copy first 2 words */
  209.     std    %g4, [%g2]
  210.     ldd    [%g1 + 8], %g4                /* copy next 2 words */
  211.     std    %g4, [%g2 + 8]
  212.  
  213.     mov    %g6, %tbr            /* switch in my trap address */
  214.     sethi    %hi(_machTBRAddr), %g2
  215.     st    %g6, [%g2 + %lo(_machTBRAddr)]    /* save tbr addr in C var */
  216.     MACH_WAIT_FOR_STATE_REGISTER()            /* let it settle for
  217.                              * the necessary
  218.                              * amount of time.  Note
  219.                              * that during this
  220.                              * wait period, we
  221.                              * may get an interrupt
  222.                              * to the old tbr if
  223.                              * interrupts are
  224.                              * disabled.  */
  225. #ifdef sun4c
  226.     sethi    %hi(_machRomVectorPtr), %g6
  227.     st    %g7, [%g6 + %lo(_machRomVectorPtr)] /* save romvec pointer */
  228. #endif
  229.         /*
  230.          * Initialize first word of restart table to show it hasn't yet
  231.          * been set up (this is a hard reboot).
  232.          */
  233.         set     reservedSpace2, %g1
  234.         add     %g1, VMMACH_PAGE_SIZE, %g1
  235.         and     %g1, ~(VMMACH_PAGE_SIZE - 1), %g1
  236.         set     _mach_RestartTablePtr, %g2
  237.         st      %g1, [%g2]
  238.         st      %g0, [%g1]
  239. #ifndef RECOV_NOCOPY
  240.         /*
  241.          * Now copy initialized data segment to storedData and set
  242.          * storedDataSize in both places to correct value.  Is etext the right
  243.          * place to start copying?  I really want the beginning of the data area
  244.          * instead.  %g1 is the src, %g2 is the destination, and %g3 is the
  245.          * amount to copy.
  246.          */
  247. CopyInitData:
  248.         set     _etext, %g1
  249.         set     _edata, %g2
  250.         sub     %g2, %g1, %g3
  251.         set     _storedDataSize, %g4
  252.         st      %g3, [%g4]
  253.         set     _storedData, %g2
  254. MoreCopying:
  255.         ldd     [%g1], %g4
  256.         std     %g4, [%g2]
  257.         add     %g1, 8, %g1
  258.         add     %g2, 8, %g2
  259.         subcc   %g3, 8, %g3
  260.         bg      MoreCopying
  261.         nop
  262. #endif /* RECOV_NOCOPY */
  263.  
  264.     call    _main
  265.     nop
  266.  
  267.     
  268. .globl    _MachTrap
  269. /*
  270.  * Reserve twice the amount of space we need for the trap table.
  271.  * Then copy machProtoVectorTable into it repeatedly, starting at
  272.  * a 4k-byte alignment.  This is dumb, but the assembler doesn't allow
  273.  * me to do much else.
  274.  *
  275.  * Note that this filler cannot use l1 or l2 since that's where pc and npc
  276.  * are written in a trap.
  277.  */
  278. .align    8
  279. machProtoVectorTable:
  280.     sethi    %hi(_MachTrap), %VOL_TEMP1    /* set _MachTrap, %VOL_TEMP1 */
  281.     or    %VOL_TEMP1, %lo(_MachTrap), %VOL_TEMP1
  282.     jmp    %VOL_TEMP1        /* must use non-pc-relative jump here */
  283.     rd    %psr, %CUR_PSR_REG
  284.  
  285. machProtoWindowOverflow:
  286.     sethi    %hi(MachHandleWindowOverflowTrap), %VOL_TEMP1
  287.     or    %VOL_TEMP1, %lo(MachHandleWindowOverflowTrap), %VOL_TEMP1
  288.     jmp    %VOL_TEMP1
  289.     rd    %psr, %CUR_PSR_REG
  290.  
  291. machProtoWindowUnderflow:
  292.     sethi    %hi(MachHandleWindowUnderflowTrap), %VOL_TEMP1
  293.     or    %VOL_TEMP1, %lo(MachHandleWindowUnderflowTrap), %VOL_TEMP1
  294.     jmp    %VOL_TEMP1
  295.     rd    %psr, %CUR_PSR_REG
  296.  
  297. machProtoLevel15Intr:
  298.     sethi    %hi(MachHandleLevel15Intr), %VOL_TEMP1
  299.     or    %VOL_TEMP1, %lo(MachHandleLevel15Intr), %VOL_TEMP1
  300.     jmp    %VOL_TEMP1
  301.     rd    %psr, %CUR_PSR_REG
  302.  
  303. .align    8
  304. reserveSpace:    .skip    0x2000
  305.  
  306. /*
  307.  * The actual space for the fast restart copy of the kernel's initialized data.
  308.  */
  309. .align 8
  310. .globl  _storedData
  311. _storedData:    .skip   MACH_RESTART_DATA_SIZE
  312. reservedSpace2: .skip   MACH_RESTART_TABLE_SIZE + VMMACH_PAGE_SIZE
  313.